#include<iostream>
#include<string>
#include<array>
#include<vector>
using namespace std;

// #define N 100

// // 静态的栈
// template<class T>
// class Stack
// {
// private:
// 	int _a[N];
// 	int _top;
// };

// int main()
// {
// 	Stack<int> st1;		// 10
// 	Stack<int> st2;		// 100

// 	return 0;
// }

// 静态的栈
template<class T, size_t N = 10>
class Stack
{
public:
	void func()
	{
		// N是常量
		N++;
	}
private:
	int _a[N];
	int _top;
};

// // C++20之前，只允许整形做非类型模板参数
// // C++20之前，可以支持double等其他内置类型
// template<double X, int* ptr>
// class A
// {};

// template<double X, string str>
// class A
// {};

// int main()
// {
// 	Stack<int> st1;				// 10
// 	Stack<int, 100>  st2;		// 100
// 	Stack<int, 1000> st3;		// 1000

// 	// 按需实例化
// 	// 不调用不报错，没有使用就没有实例化
// 	//st1.func();

// 	//A<1.1, string("1111")> aa1;

// 	return 0;
// }



// int main()
// {
// 	// 严格越界检查
// 	array<int, 10> aa1;
// 	cout << sizeof(aa1) << endl;
// 	//aa1[10];
// 	//aa1[14] = 1;

// 	// 静态
// 	int aa2[10];
// 	//aa2[11] = 1;
// 	cout << aa2[11] << endl;
// 	aa2[14] = 1;

// 	// array不如用vector。鸡肋的设计
// 	vector<int> v1(10, 1);
// 	//v1[14];
// 	cout << sizeof(v1) << endl;

// 	return 0;
// }



// void PrintVector(const vector<int>& v)
// {
// 	vector<int>::const_iterator it = v.begin();
// 	while (it != v.end())
// 	{
// 		cout << *it << " ";
// 		++it;
// 	}
// 	cout << endl;
// }


// template<class T>
// void PrintVector(const vector<T>& v)
// {
// 	// 类模板没实例化时，不去里面查细节东西,无法确认时类型还是静态变量
// 	// 加typename明确告诉是类型
// 	//typename vector<T>::const_iterator it = v.begin();
// 	auto it = v.begin();
// 	while (it != v.end())
// 	{
// 		cout << *it << " ";
// 		++it;
// 	}
// 	cout << endl;
// }

// int main()
// {
// 	vector<int> v1 = { 1,2,3,4,5,6,7 };
// 	vector<double> v2 { 1.1,2.2,3.3,4.4,5.5,6.6,7.7 };
// 	PrintVector(v1);
// 	PrintVector(v2);

// 	int i = 1;
// 	int j = {1};
// 	int k { 1 };

// 	return 0;
// }




// class Date
// {
// public:
// 	Date(int year = 1900, int month = 1, int day = 1)
// 		: _year(year)
// 		, _month(month)
// 		, _day(day)
// 	{}

// 	bool operator<(const Date& d)const
// 	{
// 		return (_year < d._year) ||
// 			(_year == d._year && _month < d._month) ||
// 			(_year == d._year && _month == d._month && _day < d._day);
// 	}

// 	bool operator>(const Date& d)const
// 	{
// 		return (_year > d._year) ||
// 			(_year == d._year && _month > d._month) ||
// 			(_year == d._year && _month == d._month && _day > d._day);
// 	}

// 	friend ostream& operator<<(ostream& _cout, const Date& d);
// private:
// 	int _year;
// 	int _month;
// 	int _day;
// };

// ostream& operator<<(ostream& _cout, const Date& d)
// {
// 	_cout << d._year << "-" << d._month << "-" << d._day;
// 	return _cout;
// }

// template<class T>
// bool Less(const T& left, const T& right)
// {
// 	return left < right;
// }

// // bool Less(Date* left, Date* right)
// // {
// // 	return *left < *right;
// // }

// // 特化
// template<>
// bool Less<Date*>(Date* const & left, Date* const & right)
// {
// 	return *left < *right;
// }

// int main()
// {
// 	Date d1(2022, 7, 7);
// 	Date d2(2022, 7, 8);
// 	cout << Less(d1, d2) << endl; // 可以比较，结果正确

// 	Date* p1 = &d1;
// 	Date* p2 = &d2;
// 	cout << Less(p1, p2) << endl; // 可以比较，结果错误

// 	return 0;
// }




// 类模板
// template<class T1, class T2>
// class Data
// {
// public:
// 	Data() { cout << "Data<T1, T2>-原模板" << endl; }
// private:
// 	T1 _d1;
// 	T2 _d2;
// };

// // 特化：针对某些特殊类型，进行特殊化处理
// // 全特化
// template<>
// class Data<int, char>
// {
// public:
// 	Data() { cout << "Data<int, char>- 全特化" << endl; }
// };

// // 偏特化/半特化
// template <class T1>
// class Data<T1, int>
// {
// public:
// 	Data() { cout << "Data<T1, int>-偏特化" << endl; }
// private:
// 	T1 _d1;
// 	int _d2;
// };

// // 限定模版的类型
// template <typename T1, typename T2>
// class Data <T1*, T2*>
// {
// public:
// 	Data() { 
// 		cout << typeid(T1).name() << endl;
// 		cout << typeid(T2).name() << endl;
// 		cout << "Data<T1*, T2*>-偏特化" << endl << endl;
// 		//T1 x1;
// 		//T1* p1;
// 	}
// };

// template <typename T1, typename T2>
// class Data <T1&, T2&>
// {
// public:
// 	Data()
// 	{
// 		cout << typeid(T1).name() << endl;
// 		cout << typeid(T2).name() << endl;
// 		cout << "Data<T1&, T2&>" << endl << endl;
// 	}
// private:
// };

// template <typename T1, typename T2>
// class Data <T1&, T2*>
// {
// public:
// 	Data()
// 	{
// 		cout << typeid(T1).name() << endl;
// 		cout << typeid(T2).name() << endl;
// 		cout << "Data<T1&, T2*>" << endl << endl;
// 	}
// private:
// };

// int main()
// {
// 	Data<int, int> d1;
// 	Data<int, char> d2;
// 	Data<int, double> d3;
// 	Data<int*, double*> d4;
// 	Data<int*, int**> d5;
// 	Data<int&, int&> d6;
// 	Data<int&, int*> d7;

// 	return 0;
// }







#include"Func.h"

int main()
{
	// 函数模版链接找不到
	Add(1, 2);     // call Z3Addii()
	Add(1.0, 2.0); // call Z3Adddd()

	Add('x', 'y'); // call Z3Addcc()


	// 普通函数可以链接找到
	func();

	return 0;
}